package JasPerl::Compiler::SimpleParser;

use strict;
use warnings;

our $TOK = qr{
  (.*?) # $1 holds text
  (?: <%@ \s* (\w+) ( (?: \s+ \w+ \s* = \s* (?: "[^"]*" | '[^']*' ) )* ) \s* %> # $2=directive $3=attrs
    | < (\w+ : \w+) ( (?: \s+ \w+ \s* = \s* (?: "[^"]*" | '[^']*' ) )* ) \s* ([/]?)> # $4=tag $5=attrs $6=close?
    | </ (\w+ : \w+) \s* > # $7=tag
    | (\${ .*? }) # $8 = expr
    | <%-- .*? --%>
    | (<%[!=]? \s* .*? \s* %>) # $9=invtag
    | $
  )
}sx;

sub new {
    my ($class, $handler) = @_;
    bless { handler => $handler }, $class;
}

sub parse {
    my ($self, $path) = @_;
    my $handler = $self->{handler};

    # FIXME: read chunks, pass line info
    my $text = _slurp($path);

    while ($text =~ /$TOK/g) {
#        print "MATCH: '$&'\n";
#        print "TEXT: '$1'\n" if $1;
#        print "DIR: '<$2> $3'\n" if $2;
#        print "TAG: '<$4> $5 <$6>'\n" if $4;
#        print "CTAG: '<$7>'\n" if $7;
#        print "NTAG: '$8'\n" if $8;

        $handler->characters($1) if length($1);
        $handler->directive($2, _attrs($3)) if $2;
        $handler->start_action(split(/:/, $4, 2), _attrs($5)) if $4;
        $handler->end_action(split(/:/, $4, 2)) if $6;
        $handler->end_action(split(/:/, $7, 2)) if $7;
        $handler->expression($8) if $8;
        die "invalid: $9\n" if $9;
    }
}

sub _attrs {
    my %attrs;
    my $s = shift;
    while ($s =~ / \s* (\w+) \s* = \s* (["']) (.*?) \2/gxs) {
        $attrs{$1} = $3;
    }
    return %attrs;
}

sub _slurp {
    my $path = shift;
    local $/ = undef;
    open(my $fh, '<', $path) or die "$path: $!\n";
    my $content = <$fh>;
    close($fh) or die "$path: $!\n";
    return $content;
}

1;
